const {composeAsync, errorRetry, increaseCallerCatch, parallelMapCatch, parallelComposeAsync} = require('../common/combinator.cjs')
const {NextError} = require('../common/exception.cjs')
const R = require('ramda')

// checkPageData 要么返回true，要么返回状态符
function pageListSpider(fetchListByPage, checkPageData, parsePageData, parallelNum, fetchDetail, checkDetail, handleDetail) {
  const pageHandler = composeAsync(
    errorRetry(fetchListByPage, 3),
    wrapNextErrorFn(checkPageData),
    parsePageData,
    R.partial(parallelMapCatch, [
      parallelNum,
      parallelComposeAsync(
        handleDetail,
        wrapNextErrorFn(
          composeAsync(
            errorRetry(fetchDetail, 3),
            checkDetail
          )
        ),
        R.identity
      )

    ])
  )
  return async function(startPage, endPage) {
    return await increaseCallerCatch(
      startPage, endPage, pageHandler
    )
  }
}

function wrapNextErrorFn(f) {
  return async function(arg) {
    const rs = await f(arg)
    if (rs === true) {
      return arg
    }
    else {
      throw new NextError(rs)
    }
  }
}


module.exports = {pageListSpider}

// 如果获取列表失败怎么办？要么中断，要么继续，这是遍历的时候做的事情。
// stateHanlder有没有必要？觉得没有必要是因为可以把接下来要做的事情封装起来，麻烦的在于没办法知道所有的错误类型。比如说detail过程中，错误超过三次就中断某一页的循环。想想还是需要的，只是可以给默认的而已。
// 当调用F连续多次抛异常，也需要捕获。那个是stateHandler的事情了？现目前确实是没办法。
